function Request()
{
	var dt = new Date();
	this.id = dt.getTime();;
	this.dt = dt.toCompact();
	this.nodes = [];
	this.attrs = [];
}

Request.prototype.toString = function()
{
    var xml = '<?xml version="1.0" encoding="utf-8" ?>';
    xml += "\n" + '<req id="'+ this.id +'" dt="'+ this.dt +'"';
	xml += attrs2str(this.attrs);
	if(this.nodes.length == 0)
	{
		xml += " />\n";
	}
	else
	{
		xml += '>'+ "\n";
		for (var i = 0; i < this.nodes.length; i++) 
			xml += this.nodes[i].toString();
		xml += '</req>';
	}
    return xml;
}

Request.prototype.createNode = function(Name)
{
	return new Node(Name);
}

Request.prototype.addNode = function(Node)
{
	Node.level = 1;
	this.nodes.push(Node);
	return this;
}

Request.prototype.addAttr = function(Name, Value)
{
	this.attrs[Name] = prepareAttrVal(Value);
	return this;
}

function Node(Name)
{
	this.level = 0;
	this.name = Name;
	this.nodes = [];
	this.attrs = [];
}

Node.prototype.addNode = function(Node)
{
	Node.level = this.level + 1;
	this.nodes.push(Node);
	return this;
}

Node.prototype.addAttr = function(Name, Value)
{
	this.attrs[Name] = prepareAttrVal(Value);
	return this;
}

Node.prototype.toString = function()
{
	var idents = "";
	for(var i = 0; i < this.level; i++)
		idents += "\t";
	
	var xml = idents + "<" + this.name;
	xml += attrs2str(this.attrs);
	
	if(this.nodes.length == 0)
	{
		xml += " />\n";
	}
	else
	{
		xml += ">\n";
		for (var i = 0; i < this.nodes.length; i++) 
			xml += this.nodes[i].toString();
		xml += idents + "</"+ this.name +">\n";
	}
	return xml;
}

function prepareAttrVal(Val)
{
    return String(Val)
		.replace(/\x0A/g, '&#010;')
		.replace(/\x0D/g, '&#013;')
		.replace(/"/g, '&#034;')
		.replace(/&/g, "&#038;")
		.replace(/'/g, "&#039;")
		.replace(/</g, "&#060;")
		.replace(/>/g, "&#062;");
}

function attrs2str(Attrs)
{
	s = "";
	for(var key in Attrs)
		s += ' '+ key + '="'+ Attrs[key] +'"';
	return s;
}